import java.util.*;

public class Global {
	LinkedList<Class> classes;
	LinkedList<Time> times;
	LinkedList<ClassRoom> rooms;
	LinkedList<Course> courses;
	LinkedList<Teacher> teachers;
	int bigestCourseSize = 0;
	int bigestRoomCapacity = 0;
	final int day = 5;
	final int startHour = 8;
	final int finishHour = 18;
	Random rand = new Random();

	// initializing random population
	// boolean initRandomGeneration() {
	//		
	// }

	/*
	 * make sure that all course exist exactly once
	 */
	boolean repair(Solution solution) {
		this.repair_stage_1(solution);
		return this.repair_stage_2(solution);
	}

	/*
	 * stage 1 of the repair function: make sure each course exist no more than
	 * once at the same time
	 */
	void repair_stage_1(Solution solution) {
		for (Class cls : this.classes) {
			// int count = 0;
			LinkedList<Location> temp = new LinkedList<Location>();
			for (Time time : times) {
				for (TimeTable tt : solution.timeTables) {
					if (cls.id == tt.getAllocation(time).id) {
						// count++;
						temp.add(new Location(tt, time));
					}
				}
			}
			while (temp.size() > 1) {
				int i = rand.nextInt(temp.size());
				Location l = temp.get(i);
				l.tt.setAllocation(new Class(), l.time);
				temp.remove(i);
			}
		}
	}

	/*
	 * stage 2 of the repair function: make sure each course at lease exist
	 * certain time.
	 */
	boolean repair_stage_2(Solution solution) {
		for (Class cls : this.classes) {
			boolean found = false;

			for (TimeTable tt : solution.timeTables) {
				if (tt.findClassinAllocation(cls)) {
					found = true;
					break;
				}
			}

			if (!found) {
				if (!this.randomlyAllocateClass(cls, solution)) {
					System.out
							.println("Can't find a place to allocate this course");
					return false;
				}
			}

		}
		return true;
	}

	private boolean randomlyAllocateClass(Class cls, Solution solution) {
		// TODO Auto-generated method stub
		int index, day, hour, id;
		TimeTable tt;
		Class tmpClass;
		int count = 0;

		do {
			count++;
			index = this.rand.nextInt(this.rooms.size());
			tt = solution.timeTables.get(index);
			day = this.rand.nextInt(5);
			hour = this.rand.nextInt(10);
			tmpClass = tt.getAllocation(new Time(day, hour));
		} while (tmpClass.id != 0 && count < 1000);
		if (count == 1000) {
			return false;
		} else {
			tt.setAllocation(cls, new Time(day, hour));
			System.out.println(cls.courseName + cls.id
					+ " is allocated to day:" + day + " hour:" + hour);
			return true;
		}

	}

	public Global() {
		this.classes = new LinkedList<Class>();
		times = new LinkedList<Time>();
		rooms = new LinkedList<ClassRoom>();
		courses = new LinkedList<Course>();
		this.teachers = new LinkedList<Teacher>();
		this.init();

	}

	void init() {
		// initialize times
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 10; j++) {
				this.times.add(new Time(i, j));
			}
		}
	}

}
